public class Main {
    public static void main(String[] args) {
        // 实例化狗类
        Dog dog = new Dog("花花", 12);
        /**
         * 此处实例对象，我就有一个疑问：
         *  子类继承父类中的字段，若是我们想让对这个字段进行封装的话，子类无法修饰，只能由父类中使用private修饰
         *  但是一旦使用private修饰，那么子类中也就无法访问了；若是使用protected修饰，那么子类的示例对象还可以访问，这个该怎么解决？
         *  -- 回答 --
         *  我认为还是需要看具体的业务场景，若是需要严格封装，那还是使用private修饰并对外提供必要接口
         *
         * 关于继承中，静态代码块、构造代码块执行先后顺序结论：
         *  总体上先父类后子类（可以理解为：因为子类依赖于父类，所以必须要先构造父类的）
         *  具体上先静态后构造
         *  并且静态代码块一个类仅会执行一次，而构造代码块会在每次实例化对象时调用
         *  因为静态代码块用于初始化静态成员，而静态成员在类生命周期中仅需初始化一次；
         *  而构造代码块用于初始化成员变量，成员变量会根据对象不同而不同*/
        // System.out.println(dog.name);
        // System.out.println(dog.age);
        // dog.bark();
        // dog.eat();
        System.out.println("================");

        // 实例化猫类
        Cat cat = new Cat("饼干", 3);
        // cat.miaow();
        // cat.eat();
    }
}

class Animal {
    /**
     * 父类，提取子类公共特性
     */
    protected String name;
    protected int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Animal() {
        /**
         * 给定无参构造方法*/
    }

    public void eat() {
        System.out.println(this.name + " 正在吃饭...");
    }

    static {
        System.out.println("Animal::静态代码块1");
    }

    static {
        System.out.println("Animal::静态代码块2");
    }

    {
        System.out.println("Animal::构造代码块");
    }
}

class Dog extends Animal {
    /**
     * 子类，继承父类所有成员变量/方法，并在其基础上进行拓展*/
    public Dog(String name, int age) {
        // 先帮助父类完成初始化
        super(name, age);
    }

    public Dog() {
        /**
         * 给定无参构造方法，在这个方法中会自动调用父类中的无参构造方法*/
    }

    public void bark() {
        /**
         * 子类特有的方法（属性），但是并非强制性，若是没有也没有关系*/
        System.out.println(this.name + " 正在汪汪叫...");
    }

    static {
        System.out.println("Dog::静态代码块");
    }

    {
        System.out.println("Dog::构造代码块");
    }
}

class Cat extends Animal {
    public Cat(String name, int age) {
        super(name, age);
    }

    public Cat() {
        /**
         * 给定无参构造方法*/
    }

    public void miaow() {
        System.out.println(this.name + " 正在猫猫叫...");
    }

    static {
        System.out.println("Cat::静态代码块");
    }

    {
        System.out.println("Cat::构造代码块");
    }
}
